package com.item.controller;

import com.item.entity.WxUser;
import com.item.redis.annocation.ApiToken;
import com.item.redis.type2.annotation.RedisLock;
import com.item.result.ResultVo;
import com.item.service.Test;
import com.item.util.ResultVoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * 场景要求：页面的数据只能被点击提交一次
 * 发生原因：由于重复点击或者网络重发，或者 nginx 重发等情况会导致数据被重复提交
 * 处理流程：数据提交前通过自定义注解拦截 创建 token，然后查询redis里是否有该token
 * 有token，证明该用户在expireTime有效期内已提交过表单，拒绝重复提交
 * 没有查询到该token，证明是首次提交或者是在expireTime有效期外又一次提交  token set放到 redis，token设置有效时间
 */

@Controller
@RequestMapping("/token")
public class TokenController {

    Integer a = 100;
    @Autowired
    Test test;

    /**
     * 1.自定义注解 @ApiToken(sign="pay",expireTime= 15000)
     * sign="pay" 操作类型标识，必填，作为key的一部分存入redis: "order" 或 "pay"
     * expireTime= 15000 间隔时间毫秒，两次提交的时间间隔 防止重复提交 默认2秒  如设置为0，则代表token一直生效  会导致该用户永远不能再次提交表单
     * <p>
     * 2.该接口可使用postman进行并发测试，执行结果只有一个请求能打印出  System.out.println("模拟表单提交");
     *
     * @return
     */
    @ApiToken(sign = "pay", expireTime = 15000)
    @PostMapping("/submit")
    @ResponseBody
    public ResultVo formSubmit(WxUser user) {

        //模拟表单提交
        System.out.println("模拟表单提交");

        return ResultVoUtil.success();
    }

    /**
     * RedisLock 注解暂时不可用 未找到原因
     *
     * @param request
     * @return
     */
    @RedisLock(fieldName = {"account"}, timeInSecond = 1000)
    @RequestMapping(value = "/submit/ajax1", method = RequestMethod.GET)
    @ResponseBody
    public ResultVo postSubmit1(HttpServletRequest request) {

        //模拟表单提交
        System.out.println("模拟表单提交");

        return ResultVoUtil.success();
    }

    /**
     * 分布式锁redission，解决并发操作
     * leaseTime： 租期
     * value： redis的key
     *
     * @param request
     * @return
     */

    @RequestMapping(value = "/submit/ajax", method = RequestMethod.GET)
    @ResponseBody
    public ResultVo postSubmit(HttpServletRequest request) {
        //模拟表单提交
        System.out.println("模拟表单提交" + a);
        test.tets("zhx");
        return ResultVoUtil.success();
    }

    @RequestMapping(value = "/submit/ajax2", method = RequestMethod.GET)
    @ResponseBody
    public ResultVo postSubmi22222t(HttpServletRequest request) {
        //模拟表单提交
        System.out.println("模拟表单提交2222" + a);
        test.tets("aaa");
        return ResultVoUtil.success();
    }

}

